#include <iostream>
#include <string.h>
#include <unistd.h>
#include <pthread.h>

using namespace std;

// #define TNUM 4
// typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);
// volatile bool quit=false;

// class ThreadData
// {
// public:
//     ThreadData(const string& name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
//     :_name(name)
//     ,_func(func)
//     ,_mutex(mutex)
//     ,_cond(cond)
//     {

//     }
// public:
//     string _name;
//     func_t _func;
//     pthread_mutex_t* _mutex;
//     pthread_cond_t* _cond;
// };

// void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 下载"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         if(!quit)
//         {
//             cout<<"running -- 打印"<<endl;
//         }
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 刷新"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func4(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 读取数据"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;

//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3,func4};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread ";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td);
//     }
//     sleep(1);
//     int cnt=10;
//     while(cnt)
//     {
//         cout<<"resume"<<cnt--<<endl;
//         pthread_cond_signal(&cond);
//         sleep(1);
//     }

//     cout<<"ctrl done"<<endl;
//     quit=true;
//     //将所有的线程全部唤醒
//     pthread_cond_broadcast(&cond);
//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//         sleep(1);
//         cout<<"thread: "<<tid[i]<<" quit"<<endl;
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }
// #define TNUM 4
// volatile bool quit=false;
// typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);


// class ThreadData
// {
//     ThreadData(const string& name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
//     :_name(name)
//     ,_func(func)
//     ,_mutex(mutex)
//     ,_cond(cond)
//     {

//     }
// public:
//     string _name;
//     func_t _func;
//     pthread_mutex_t* _mutex;
//     pthread_cond_t* _cond;
// };

// void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 下载"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_t(mutex);
//         pthread_cond_wait(cond,mutex);
//         if(!quit)
//         {
//             cout<<"running -- 下载"<<endl;
//         }
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 刷新"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func4(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_t(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 打印"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }
// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;

//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3,func4};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td);
//     }
//     sleep(5);
//     quit=false;
//     int cnt=5;
//     while(cnt)
//     {
//         pthread_cond_signal(&cond);
//         sleep(1);
//         cout<<"resume thread run code"<<cnt--<<endl;
//     }
//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }

// volatile bool quit=false;
// #define TNUM 4
// typedef void (*func_t)(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond);


// class ThreadData
// {
// public:
//     ThreadData(const string& name,func_t func,pthread_mutex_t* mutex,pthread_cond_t* cond)
//     :_name(name)
//     ,_func(func)
//     ,_mutex(mutex)
//     ,_cond(cond)
//     {

//     }
// public:
//     string _name;
//     func_t _func;
//     pthread_mutex_t* _mutex;
//     pthread_cond_t* _cond;
// };

// void func1(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 下载"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }

// void func2(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         if(!quit)
//         {
//             cout<<"running -- 打印"<<endl;
//         }
//     }
// }
// void func3(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 刷新"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }
// void func4(const string& name,pthread_mutex_t* mutex,pthread_cond_t* cond)
// {
//     while(!quit)
//     {
//         pthread_mutex_lock(mutex);
//         pthread_cond_wait(cond,mutex);
//         cout<<"running -- 输出"<<endl;
//         pthread_mutex_unlock(mutex);
//     }
// }

// void* Entry(void* args)
// {
//     ThreadData* td=(ThreadData*)args;
//     td->_func(td->_name,td->_mutex,td->_cond);
//     delete td;
//     return nullptr;
// }

// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_cond_t cond;

//     pthread_mutex_init(&mutex,nullptr);
//     pthread_cond_init(&cond,nullptr);

//     pthread_t tid[TNUM];
//     func_t funcs[TNUM]={func1,func2,func3,func4};
//     for(int i=0;i<TNUM;i++)
//     {
//         string name="thread";
//         name+=to_string(i+1);
//         ThreadData* td=new ThreadData(name,funcs[i],&mutex,&cond);
//         pthread_create(tid+i,nullptr,Entry,(void*)td); 
//     }
//     sleep(5);
//     int cnt=5;
//     while(cnt--)
//     {
//         pthread_cond_signal(&cond);
//         cout<<"thread signal"<<cnt<<endl;
//         sleep(1);
//     }
//     quit=true;

//     for(int i=0;i<TNUM;i++)
//     {
//         pthread_join(tid[i],nullptr);
//         cout<<"thread join"<<tid[i]<<endl;
//         sleep(1);
//     }
//     pthread_mutex_destroy(&mutex);
//     pthread_cond_destroy(&cond);
//     return 0;
// }